/*
尽可能还原 Promise 中的每一个 API, 并通过注释的方式描述思路和原理.
*/

const { reject } = require("lodash")


// promise 三种状态 状态不可逆
const PENDING = 'pending' // 初始化
const FULFILLED = 'fulfilled' // 成功
const REJECTED = 'rejected' // 失败


class MyPromise {

    constructor(executor) {
        executor(this.resolve, this.reject)
    }

    // 初始化状态
    status = PENDING

    // 成功参数
    successValue = undefined

    // 失败参数
    rejectedValue = undefined

    // 成功回调
    successCallBack = undefined

    // 失败回调
    failCallBack = undefined

    // resolve 方法实现
    resolve = (value) => {

        // 判断状态是否等于PENDING
        if (this.status !== PENDING) {return}

        // 改变状态
        this.status = FULFILLED

        // 保存成功之后的值
        this.successValue = value

        // 调用失败回调
        this.successCallBack && this.successCallBack(value)
    }

    // reject 方法实现
    reject = (value) => {

        // 判断状态是否等于PENDING
        if (this.status !== PENDING) {return}

        // 改变状态
        this.status = REJECTED

        // 保存失败之后的值
        this.rejectedValue = value

        // 调用成功回调
        this.failCallBack && this.failCallBack(value)
    }

    // then 方法实现
    then (successFn = undefined, failFn = undefined) {
        
        let newPromise = new MyPromise((resolve, reject) => {
            // 判断状态
            if (this.status === FULFILLED) {

                // 成功回调
                let successFnValue = successFn(this.successValue)

                // 判断是promise对象还是普通值
                isPromiseCallBack(successFnValue, resolve, reject)

            } else if (this.status === REJECTED) {

                // 失败回调
                failFn(this.rejectedValue)

            } else {
                // 处理异步逻辑，保存回调函数
                this.successCallBack = successFn
                this.failCallBack = failFn
            }
        })

        return newPromise
    }


    // catch方法实现

    catch(failFn) {
        return this.then(undefined, failFn)
    }

    // all 方法实现
    static all (array = []) {
        let result = []

        // 返回promise对象
        return new MyPromise( (resolve, reject) => {

            // 判断数组是否已经执行完毕
            const resultAddData = (index, value) => {
                result[index] = value

                if (array.length === result.length) {
                    resolve(result)
                }
            }

            // 循环数组，获取结果
            array.forEach((item, index) => {

                
                // 判断是否promise对象
                if (item instanceof MyPromise) {
                    // promise 对象
                    item.then(value => {resultAddData(index, value)}, (reason) => {reject(reason)})
                } else {
                    // 普通值
                    resultAddData(index, item)
                }

                
            })

        
            resolve(resolve)

        })

    }

    // resolve 静态方法实现
    static resolve(value) {
        if (value instanceof MyPromise) { return value }
        
        return new Promise(resolve => resolve(value))
    }
}


const isPromiseCallBack = (successFnValue, resolve, reject) => {
    if (successFnValue instanceof MyPromise) {
        // promise 对象
        successFnValue.then(resolve, reject)
    } else {
        // 普通值
        resolve(successFnValue)
    }
}